package www.configure.all.modules.websocket;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import www.configure.all.modules.domain.CommonUtils;
import www.configure.all.modules.domain.LocalProperties;
import www.configure.all.modules.domain.R;

import java.io.*;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import okhttp3.*;

@Component
public class StatusChangeWebsocketHandler extends TextWebSocketHandler {

	private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();

	// 服务器连接池<port, status>
	private static final Map<Integer, String> serverLinkInfo = new ConcurrentHashMap<>();

	// 端口对应的进程<port, pid>
	private static final Map<Integer, Long> portPidInfo = new ConcurrentHashMap<>();

	// 当前服务器ip，启动进程时保存，断开长连接时使用
	private static final AtomicReference<String> nowServerIp = new AtomicReference<>("");

	// 当前最大连接数
	private static final AtomicReference<Integer> maxLink = new AtomicReference<>(3);

	// 正在使用的用户信息<sessionKey,port>
	private static final Map<String, Integer> useLinkInfo = new ConcurrentHashMap<>();

	// 正在使用的用户ip<sessionKey,ip>
	private static final Map<String, String> useIpInfo = new ConcurrentHashMap<>();

	// 队列中的用户信息
	private static final List<String> queueLinkInfo = new CopyOnWriteArrayList<>();

	// 待使用的port端口，有序数组，每次取第一个
	private static final Set<Integer> postSet = new LinkedHashSet<>();

	private LocalProperties localPath;

	private RedissonClient redissonClient;

	private Boolean firstStart = true;

	//端口偏移值
	private static int offsetValue = 1000;

	public StatusChangeWebsocketHandler(LocalProperties localPath, RedissonClient redissonClient) {
		this.localPath = localPath;
		this.redissonClient = redissonClient;
	}

	static {
		// 初始化 15010-15019
		for (int port = 16010; port <= 16018; port++) {
			postSet.add(port);
		}
	}
// ***能启动多少个就启动多少个的时候使用
//	static {
//		try {
//			// 获取本机 IP 地址
//			InetAddress inetAddress = InetAddress.getLocalHost();
//			nowServerIp.set(inetAddress.getHostAddress());
//		} catch (UnknownHostException e) {
//			e.printStackTrace();
//			nowServerIp.set("unknown");
//		}
//	}
//
//	public static String getNowServerIp() {
//		return nowServerIp.get();
//	}

	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		RLock lock = redissonClient.getLock("newSocketLock");
		try {
			// 尝试获取锁，最多等待20秒，锁的持有时间为10秒
			boolean isLocked = lock.tryLock(20, 10, java.util.concurrent.TimeUnit.SECONDS);
			if (isLocked) {
				// 成功获取锁，执行业务逻辑
				System.out.println("获取到锁，开始执行业务");

				String pathQuery = session.getUri().getQuery();
				Map<String, String> paramMap = CommonUtils.formatUrlParams(pathQuery);

				String ts = paramMap.get("ts");
				String realName = paramMap.get("realName");
				String userName = paramMap.get("userName");

				String sessionKey = realName + "^^^" + userName + "^^^" + ts;

				String clientIp = (String) session.getAttributes().get("clientIp");
				useIpInfo.put(sessionKey,clientIp);

				if(sessions.get(sessionKey) == null){
					sessions.put(sessionKey, session);
				}

				for (Integer port : serverLinkInfo.keySet()) {
					if(serverLinkInfo.get(port).equals("0")){
						// 修改端口状态
						serverLinkInfo.put(port, "1");
						// 向正在使用的用户队列中添加信息
						useLinkInfo.put(sessionKey, port);

						JSONObject result = new JSONObject();
						result.put("code", 200);
						result.put("port", port);
						result.put("status", 1);
						// 找到一个以后就结束遍历
						break;
					}
				}
				if (useLinkInfo.get(sessionKey) == null){
					queueLinkInfo.add(sessionKey);
				}
				sendMessageByServerIp();

				if (useLinkInfo.get(sessionKey) == null){
					//当前资源池小于最大连接数，则新启动一个端口
					if(serverLinkInfo.size() < maxLink.get()){
						System.out.println("资源池有剩余，新启端口");
						startServer();
					}
				}
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			// 释放锁
			if (lock.isHeldByCurrentThread()) {
				lock.unlock();
				System.out.println("释放锁");
			}
		}
	}

	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		String pathQuery = session.getUri().getQuery();
		Map<String, String> paramMap = CommonUtils.formatUrlParams(pathQuery);

		String ts = paramMap.get("ts");
		String realName = paramMap.get("realName");
		String userName = paramMap.get("userName");

		String sessionKey = realName + "^^^" + userName + "^^^" + ts;
		System.out.println("断开长连接sessionKey :" + sessionKey);

		sessions.remove(sessionKey);
		useIpInfo.remove(sessionKey);
		queueLinkInfo.remove(sessionKey);
		// 杀死端口
//		if (useLinkInfo.get(sessionKey) != null){
//			Integer port = useLinkInfo.get(sessionKey);
//			System.out.println("需要重置的ue端口:" + port);
//
//			useLinkInfo.remove(sessionKey);
//
//			// 发起请求，重置UE
//			OkHttpClient client = new OkHttpClient.Builder()
//					.connectTimeout(10, TimeUnit.MINUTES)  // 连接超时
//					.readTimeout(10, TimeUnit.MINUTES)     // 读取超时
//					.writeTimeout(10, TimeUnit.MINUTES)    // 写入超时
//					.build();
//			String result;
//
//			String url = "http://" + nowServerIp + ":" + (port -10 ) + "/element/clear";
//			System.out.println("UE的地址：" + url);
//
//			RequestBody emptyBody = RequestBody.create(new byte[0]);
//			Request request = new Request.Builder()
//					.url(url)
//					.post(emptyBody)
//					.build();
//
//			Boolean isSuccess = true;
//			try (Response response = client.newCall(request).execute()) {
//				if (response.isSuccessful()) {
//					result = response.body().string();
//					changeUeStatus(String.valueOf(port -10));
//					System.out.println("clear成功结果:"+result);
//				} else {
//					// 处理非成功响应
//					result = "请求失败，响应码：" + response.code();
//					System.out.println("clear失败结果:"+result);
//					isSuccess = false;
//				}
//			} catch (Exception e) {
//				// 处理异常
//				result = "请求异常：" + e.getMessage();
//				System.out.println("clear异常结果:"+result);
//				isSuccess = false;
//			} finally {
//				String landUrl = "http://" + nowServerIp + ":" + (port -10 ) + "/land/visible";
//				System.out.println("landUrl的地址：" + landUrl);
//
//
//				JSONObject json = new JSONObject();
//				json.put("show", false);
//				RequestBody landBody = RequestBody.create(json.toJSONString(), MediaType.get("application/json; charset=utf-8"));
//				Request landRequest = new Request.Builder()
//						.url(landUrl)
//						.post(landBody)
//						.build();
//				try (Response response = client.newCall(landRequest).execute()) {
//					if (response.isSuccessful()) {
//						result = response.body().string();
//						changeUeStatus(String.valueOf(port -10));
//						System.out.println("visible成功结果:"+result);
//					} else {
//						// 处理非成功响应
//						result = "请求失败，响应码：" + response.code();
//						System.out.println("visible失败结果:"+result);
//						isSuccess = false;
//					}
//				} catch (Exception e) {
//					// 处理异常
//					result = "请求异常：" + e.getMessage();
//					System.out.println("visible异常结果:"+result);
//					isSuccess = false;
//				}
//			}
//			if(!isSuccess){
//				System.out.println("ue接口请求异常，执行端口重启逻辑！");
//				killPortServer(port);
//				startServer();
//			}
//
//		}

		//执行重启逻辑
		if (useLinkInfo.get(sessionKey) != null){
			System.out.println("执行端口重启逻辑！");
			Integer port = useLinkInfo.get(sessionKey);
			if(useLinkInfo.size() == 1 || queueLinkInfo.size() > 0){
				System.out.println("唯一端口，执行重启逻辑:" + port);
				useLinkInfo.remove(sessionKey);
				killPortServer(port);
				startServer();
			}else{
				System.out.println("非唯一端口，执行杀掉逻辑:" + port);
				useLinkInfo.remove(sessionKey);
				killPortServer(port);
			}
		}

		sendMessageByServerIp();
	}

	// 容器名称
	private static final String CONTAINER_NAME = "mycoturn";
	// 镜像名称
	private static final String IMAGE_NAME = "docker.1ms.run/coturn/coturn";
	// 配置文件挂载路径
	private static final String CONFIG_MOUNT = "/mnt/baidu/app/turnserver.conf:/etc/coturn/turnserver.conf";

	/**
	 * 杀掉turn服务并重启
	 */
	public void startTurn() {
		System.out.println("初始化turn服务");

		try {
			// 停止容器
			ProcessBuilder stopPb = new ProcessBuilder("docker", "stop", CONTAINER_NAME);
			stopPb.start();

			// 删除容器
			ProcessBuilder rmPb = new ProcessBuilder("docker", "rm", CONTAINER_NAME);
			rmPb.start();

			ProcessBuilder pb = new ProcessBuilder(
					"docker", "run", "-d",
					"-p", "15050:3478",
					"-p", "15050:3478/udp",
					"-p", "15051-15099:15051-15099/udp",
					"-v", CONFIG_MOUNT,
					"--network=host",
					"--name=" + CONTAINER_NAME,
					IMAGE_NAME
			);
			pb.start();
			System.out.println("初始化turn服务成功");
		}catch (Exception e){
			e.printStackTrace();
			System.out.println("turn服务执行异常");
		}

	}

	/**
	 * 启动初始化
	 */
	public Integer startServer() {
		System.out.println("进入一次startServer");
		Integer port = null;
		try{
//			while (true) {
//				port = ThreadLocalRandom.current().nextInt(15010, 15020);
//				if (!serverLinkInfo.containsKey(port)) {
//					break;
//				}
//
//			}
			if (postSet.isEmpty()) {
				return null;
			}
			Iterator<Integer> iterator = postSet.iterator();
			Integer firstPort = iterator.next();
			iterator.remove(); // 移除第一个元素
			port = firstPort;
//			port = 25555;

			// 信令服务器 streamer_port为port player_port为port+20 sfu_port为port+30
			List<String> cmdList = Arrays.asList(
					"docker", "run", "-d",
					"--name", "signalling-" + port,
					"-p", port + ":9416",
					"-p", (port + 20) + ":19416",
					"-p", (port + 30) + ":19516",
					"-v", "/mnt/baidu/app/uestart.sh:/SignallingWebServer/SignallingWebServer/platform_scripts/bash/start_with_turn.sh",
					"-v", "/mnt/baidu/app/common.sh:/SignallingWebServer/SignallingWebServer/platform_scripts/bash/common.sh",
					"-v", "/mnt/baidu/app/config.json:/SignallingWebServer/SignallingWebServer/config.json",
					"signalling:ue"
			);

			ProcessBuilder signalling = new ProcessBuilder(cmdList);
			signalling.start();

			// 像素流PixelStreamingURL（streamer_port） port
			// ueHttp port-10
			// ue长连接 port + 10

			String logFileName = "./log_" + port + "_" + System.currentTimeMillis() + ".log";
			String uePath = localPath.getPath() + "TwinBaseGH55-Linux-Shipping";
			List<String> command = Arrays.asList(
					uePath,
					"-RenderOffScreen",
					"-PixelStreamingURL=ws://" + nowServerIp + ":" + port,
					"-PixelStreamingKeyFilter=F5",
					"-MyWebsocketPort=" + (port + 10),
					"-MyHttpPort=" + (port - 10),
					"-Log=./" + logFileName
			);

			ProcessBuilder builder = new ProcessBuilder(command);
			Process process = builder.start();

			consumeStream(process.getInputStream(), "[UE OUT]");
			consumeStream(process.getErrorStream(), "[UE ERR]");
			long pid = getPidFromProcess(process);
			portPidInfo.put(port, pid);

			serverLinkInfo.put(port, "2");

			return port;
		}catch (Exception e){
			e.printStackTrace();
		}
		return port;
	}

	/**
	 * 通过反射获取进程
	 * @param process
	 * @return
	 */
	private static long getPidFromProcess(Process process) {
		try {
			if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
				Field pidField = process.getClass().getDeclaredField("pid");
				pidField.setAccessible(true);
				return pidField.getLong(process);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return -1;
	}

	/**
	 * 关闭指定端口
	 */
	public Integer killPortServer(Integer port) {
		try{
			// 信令服务器 streamer_port为port player_port为port+20 sfu_port为port+30
			List<String> cmdList = Arrays.asList(
					"docker", "rm", "-f", "signalling-" + port
			);

			ProcessBuilder signalling = new ProcessBuilder(cmdList);
			signalling.start();

			Long pid = portPidInfo.get(port);
			if (pid != null) {
				Process killProcess = new ProcessBuilder("kill", "-9", pid.toString()).start();
				int killExitCode = killProcess.waitFor();

				if (killExitCode == 0) {
					System.out.println("成功关闭UE，进程 " + pid + "   端口：" + port);
				} else {
					System.err.println("关闭UE失败，进程 " + pid + ", exit code: " + killExitCode + "   ，端口：" + port);
				}
			} else {
				System.err.println("没有找到port对应的pid " + port);
			}

			portPidInfo.remove(port);
			serverLinkInfo.remove(port);

			postSet.add(port);

			//移除正在使用该端口的连接，并将会话消息放入队列中
			for (String s : useLinkInfo.keySet()) {
				if(port.intValue() == useLinkInfo.get(s)){
					useLinkInfo.remove(s);
					queueLinkInfo.add(0,s);
				}
			}
			sendMessageByServerIp();

		}catch (Exception e){
			e.printStackTrace();
		}
		return port;
	}

	/**
	 * 启动初始化
	 */
	public R updateServerLink(Integer clientNum,String serverIp) {
//		maxLink.set(clientNum);
		nowServerIp.set(serverIp);
		Integer clientNow = serverLinkInfo.size();
		if (clientNum < clientNow ){
			//超过了资源池的数量，需要扣减资源池的信息
			int killNum = clientNow - clientNum;
			List<Integer> portsToRemove = serverLinkInfo.keySet().stream()
					.limit(killNum)
					.collect(Collectors.toList());

			// 关闭端口并清理资源
			portsToRemove.forEach(port -> {
				killPortServer(port); // 内部已清理 portPidInfo 和 serverLinkInfo

				// 清理关联的客户端会话
				List<String> sessionsToRemove = useLinkInfo.entrySet().stream()
						.filter(entry -> Objects.equals(entry.getValue(), port))
						.map(Map.Entry::getKey)
						.collect(Collectors.toList());

				sessionsToRemove.forEach(session -> {
					useLinkInfo.remove(session);
					queueLinkInfo.add(session);
				});
			});

			sendMessageByServerIp();
			return R.ok();
		}
		if (clientNum > clientNow) {
			//增加资源池
			Integer k = clientNum - clientNow;
			for (int i = 0; i < k; i++) {
				startServer();
			}
		}
		return R.ok();
	}

	/**
	 * 广播信息
	 */
	public static void sendMessageByServerIp() {
		JSONObject message = new JSONObject();

		List<JSONObject> useLinkList = new ArrayList<>();
		List<JSONObject> queueLinkList = new ArrayList<>();

		for (String s : useLinkInfo.keySet()) {
			JSONObject json = new JSONObject();
			json.put("sessionKey", s);
			json.put("ueHttpPort", useLinkInfo.get(s) - offsetValue - 10);
//			json.put("uewsPort", useLinkInfo.get(s));
			json.put("webSocketPort", useLinkInfo.get(s) - offsetValue +10);
			json.put("signallingPort", useLinkInfo.get(s) - offsetValue +20);
			json.put("clientIp", useIpInfo.get(s));

			String[] strings = s.split("\\^\\^\\^");
			String realName = null;
			String userName = null;
			if (strings.length >= 2) {
				realName = strings[0];
				userName = strings[1];
			} else {
				System.out.println("queueKey 拆分失败，长度不足 2，值为: { " + s + "}");
			}

			json.put("realName", realName);
			json.put("userName", userName);
			Long ts = Long.valueOf(s.substring(s.lastIndexOf("^^^") + 3));
			json.put("ts", ts);
			useLinkList.add(json);
		}
		for (String s : queueLinkInfo){
			JSONObject json = new JSONObject();
			json.put("sessionKey", s);
			json.put("ueHttpPort", -1);
			json.put("webSocketPort", -1);
			json.put("signallingPort", -1);
			json.put("clientIp", useIpInfo.get(s));

			String[] strings = s.split("\\^\\^\\^");
			String realName = null;
			String userName = null;
			if (strings.length >= 2) {
				realName = strings[0];
				userName = strings[1];
			} else {
				System.out.println("queueKey 拆分失败，长度不足 2，值为: { " + s + "}");
			}
			json.put("realName", realName);
			json.put("userName", userName);
			Long ts = Long.valueOf(s.substring(s.lastIndexOf("^^^") + 3));
			json.put("ts", ts);
			queueLinkList.add(json);
		}
		message.put("useLinkList",useLinkList);
		message.put("queueLinkList",queueLinkList);
		message.put("maxLink",maxLink);
		for (String s : sessions.keySet()) {

			WebSocketSession session = sessions.get(s);
			if (session == null){
				continue;
			}
			if (!session.isOpen()) {
				continue;
			}
			try {
				session.sendMessage(new TextMessage(message.toJSONString()));
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("用户【"+s+"】推送信息失败");
			}

		}
	}


	public R ueForward(JSONObject input) {
		OkHttpClient client = new OkHttpClient();
		String result = null;
		MediaType JSON = MediaType.get("application/json; charset=utf-8");

		for (Integer port : serverLinkInfo.keySet()) {
			String url = "http://" + nowServerIp + ":" + (port - 10) + "/ModelUpload/fileList";
			System.out.println("UE的地址：" + url);

			RequestBody body = RequestBody.create(input.toJSONString(), JSON);
			Request request = new Request.Builder()
					.url(url)
					.post(body)
					.build();

			try (Response response = client.newCall(request).execute()) {
				if (response.isSuccessful()) {
					result = response.body().string();
					System.out.println("result:"+result);
					break;
				} else {
					// 处理非成功响应
					result = "请求失败，响应码：" + response.code();
					System.out.println("result:"+result);
				}
			} catch (Exception e) {
				// 处理异常
				result = "请求异常：" + e.getMessage();
				System.out.println("result:"+result);
			}
		}
		return R.ok(result);
	}

	private void consumeStream(InputStream inputStream, String prefix) {
		new Thread(() -> {
			try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
				String line;
				while ((line = reader.readLine()) != null) {
					System.out.println(prefix + " " + line);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}).start();
	}

	private boolean isPortInUse(int port) {
		try (Socket ignored = new Socket(String.valueOf(nowServerIp), port)) {
			return true;
		} catch (IOException ignored) {
			return false;
		}
	}

	public void changeUeStatus(String input) {
		Integer uePort = Integer.valueOf(input) + 10;
		System.out.println("ue启动端口：" + uePort);
		serverLinkInfo.put(uePort, "0");
		if (!queueLinkInfo.isEmpty()) {
			Long minTs = null;
			String queueKey = null;
			for (String s : queueLinkInfo) {
				try {
					Long listMinTs = Long.valueOf(s.substring(s.lastIndexOf("^^^") + 3));
					if (minTs == null || listMinTs < minTs) {
						minTs = listMinTs;
						queueKey = s;
					}
				} catch (NumberFormatException e) {
					System.err.println("sessionKey 格式错误: " + s);
				}
			}

//			String clientIp = useIpInfo.get(queueKey);;
//			useIpInfo.put(queueKey,clientIp);

			for (Integer port : serverLinkInfo.keySet()) {
			System.out.println("当前port:" + port);
				if(serverLinkInfo.get(port).equals("0")){
					// 修改端口状态
					serverLinkInfo.put(port, "1");
					// 向正在使用的用户队列中添加信息
					useLinkInfo.put(queueKey, port);

					JSONObject result = new JSONObject();
					result.put("code", 200);
					result.put("port", port);
					result.put("status", 1);
					// 找到一个以后就结束遍历
					break;
				}
			}
			queueLinkInfo.remove(queueKey);
			System.out.println("queueKey的值: " + queueKey);
		}
		sendMessageByServerIp();
	}

	public Object getInfo() {
		Map<String, Object> result = new HashMap<>();
		result.put("serverLinkInfo", serverLinkInfo);
		result.put("portPidInfo", portPidInfo);
		result.put("useLinkInfo", useLinkInfo);
		result.put("useIpInfo", useIpInfo);
		result.put("queueLinkInfo", queueLinkInfo);
		result.put("postSet", postSet);
		return result;
	}

	/**
	 * UE崩溃重启
	 */
	public void restartUe() throws IOException, InterruptedException {
		// 等待5秒释放异常进程
		Thread.sleep(5000);
		for (Integer port : portPidInfo.keySet()) {
			// 查看端口占用情况
			List<String> command = Arrays.asList("bash", "-c", "lsof -i:" + port);

			ProcessBuilder builder = new ProcessBuilder(command);
			builder.redirectErrorStream(true); // 将错误流也合并进输出流
			Process process = builder.start();

			try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
				StringBuilder output = new StringBuilder();
				String line;
				while ((line = reader.readLine()) != null) {
					output.append(line).append("\n");
				}

				if (output.toString().trim().isEmpty()) {
					System.out.println("端口" + port + "没有进程使用");
					killPortServer(port);
					startServer();
				} else {
					System.out.println("检测到端口 " + port + " 有进程使用：\n" + output);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public String getGpuStatus() {
		StringBuilder result = new StringBuilder();
		try {
			Process process = Runtime.getRuntime().exec("nvidia-smi --query-gpu=memory.total,memory.free --format=csv,noheader,nounits");
			BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

			String line;
			int gpuIndex = 0;
			while ((line = reader.readLine()) != null) {
				String[] memInfo = line.trim().split(",\\s*");
				String lineResult = String.format("GPU %d -> 总显存: %s MiB, 剩余显存: %s MiB", gpuIndex, memInfo[0], memInfo[1]);
				result.append(lineResult).append("\n");
				gpuIndex++;
			}

			process.waitFor();
		} catch (Exception e) {
			e.printStackTrace();
			return "获取 GPU 状态失败：" + e.getMessage();
		}
		return result.toString();
	}

//	// ***能启动多少个就启动多少个的时候使用
//	/**
//	 * UE崩溃重启
//	 */
//	public void restartUe() throws InterruptedException {
//		// 等待20秒释放异常进程
//		Thread.sleep(10 * 1000);
//		OkHttpClient client = new OkHttpClient();
//		String result = null;
//		for (Integer port : portPidInfo.keySet()) {
//			// 查看端口占用情况
////			List<String> command = Arrays.asList("bash", "-c", "lsof -i:" + port);
//
////			ProcessBuilder builder = new ProcessBuilder(command);
////			builder.redirectErrorStream(true); // 将错误流也合并进输出流
////			Process process = builder.start();
//
////			try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
////				StringBuilder output = new StringBuilder();
////				String line;
////				while ((line = reader.readLine()) != null) {
////					output.append(line).append("\n");
////				}
////				System.out.println("查看端口情况：" + output.toString().trim());
//			String url = "http://" + nowServerIp + ":" + (port - 10) + "/camera/get";
//
//			RequestBody emptyBody = RequestBody.create(new byte[0]);
//			Request request = new Request.Builder()
//					.url(url)
//					.post(emptyBody)
//					.build();
//
//			try (Response response = client.newCall(request).execute()) {
//
//				if (response.isSuccessful()) {
//					System.out.println("检测到端口 " + port + " 有进程使用");
//				}
//			} catch (IOException e) {
//				result = "请求异常：" + e.getMessage();
//				System.out.println("result:"+result);
//				System.out.println("端口" + port + "没有进程使用");
//				killPortServer(port);
//				if (!firstStart && portPidInfo.size() < maxLink.get()) {
//					startServer();
//				}
//				if (firstStart) {
//					firstStart = false;
//					maxLink.set(portPidInfo.size());
//					System.out.println("当前最大连接数：" + maxLink.get());
//				}
//			}
//		}
//	}
//
//
//	public void startLogMonitor() {
//		File logFile = new File("./monitoring.log");
//		ExecutorService executor = Executors.newSingleThreadExecutor();
//		executor.submit(() -> {
//			try (BufferedReader reader = new BufferedReader(new FileReader(logFile))) {
//				String line;
//				while ((line = reader.readLine()) != null) { }
//				while (true) {
//					line = reader.readLine();
//					if (line != null) {
//						if (line.contains("[UE OUT] Engine crash handling finished; re-raising signal 11")) {
//							handleCrash();
//						}
//						if (maxLink.get() == 0 || portPidInfo.size() < maxLink.get()) {
//							if (line.contains("ue启动端口：")) {
//								System.out.println("上一个UE启动成功，准备启动下一个");
//								startServer();
//							}
//						}
//					} else {
//						Thread.sleep(100);
//					}
//				}
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//		});
//	}
//
//	private void handleCrash() throws InterruptedException {
//		System.out.println("检测到 UE 崩溃日志，执行对应逻辑...");
//		restartUe();
//	}

}
